package com.running.mobile;


import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;

import org.apache.commons.lang.StringUtils;

import com.isomorphic.base.Base;
import com.isomorphic.datasource.DSField;
import com.isomorphic.datasource.DSRequest;
import com.isomorphic.datasource.DSResponse;
import com.isomorphic.datasource.DataSource;
import com.isomorphic.log.Logger;
import com.isomorphic.util.DataTools;
import com.isomorphic.util.ErrorReport;

/**
 * 批量上传类
 * @author 崔海亮
 */
public class BatchUpload extends Base
{
	private static Logger log = new Logger(BatchUpload.class.getName());

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public DSResponse batchUpload(DSRequest dsRequest)
	throws Exception
	{
		String dsName = (String)dsRequest.getValues().get("dsName");
		DataSource ds = DataSource.forName(dsName, dsRequest);

		Map columnMap = new HashMap();
		for (Iterator i = ds.getFieldNames().iterator(); i.hasNext(); ) {
			String fieldName = (String)i.next();
			DSField field = ds.getField(fieldName);
			if (field.get("uploadFieldName") != null)
				columnMap.put(field.get("uploadFieldName"), fieldName);
			else {
				columnMap.put(fieldName, fieldName);
			}

			String title = (String)field.get("title");
			if ((title != null) && 
					(!(columnMap.containsValue(title)))) {
				columnMap.put(title, fieldName);
			}

		}

		Map data = new HashMap();
		InputStream is = dsRequest.getUploadedFileStream("file");
//		DataImport di = new DataImport();
		//List rows = di.importToRows(new InputStreamReader(is), columnMap);
		List rows = importToRows(is, columnMap);
		log.debug("Rows: " + DataTools.prettyPrint(rows));

		List errors = validateRows(rows, ds);

		data.put("gridRows", rows);
		if (errors.size() != 0) data.put("errors", errors);

		DSResponse dsResponse = new DSResponse(ds);

		dsResponse.setData(data);

		return dsResponse;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private List importToRows(InputStream is, Map columnMap) throws BiffException, IOException {
		Workbook workbook = Workbook.getWorkbook(is);
		
		Sheet mainSheet = workbook.getSheet(0);
		
		int rows=mainSheet.getRows();
		
		String[] fileds = new String[mainSheet.getColumns()];//内容与BEAN中的字段名对应,INDEX与EXCEL中的列INDEX对应
		//有数据时初始化fileds
		if(rows>1){
			for(int a = 0; a < mainSheet.getColumns(); a++){
				String excelColName = mainSheet.getCell(a,0).getContents();
				Object field = columnMap.get(excelColName);
				if(field != null)
					fileds[a] = (String)field;
			}
		}else{
			return new ArrayList();
		}
		//循环每行数据，取出放入最终LIST中
		List maps = new ArrayList();
		for(int rowNum=1;rowNum<rows;rowNum++){
			Map map= new HashMap(); 
			boolean empty = true;//标识该条记录是否为空
			for(int colNum = 0; colNum < fileds.length; colNum++){
				String field = fileds[colNum];
				if(!StringUtils.isBlank(field)){
					String contents =mainSheet.getCell(colNum,rowNum).getContents();
					map.put(field, contents);
					if(!StringUtils.isBlank(contents)){
						empty = false;
					}
				}
			}
			if(!empty){
				maps.add(map);
			}
		} //end row for
		workbook.close();
		return maps;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private List validateRows(List rows, DataSource ds)
	throws Exception
	{
		List fieldNames = ds.getFieldNames();

		List errors = new ArrayList();

		int rowNum = 0;
		for (Iterator i = rows.iterator(); i.hasNext(); ) {
			Map row = (Map)i.next();
			ErrorReport er = ds.validate(row, true);
			if (er != null) {
				Map rowError = new HashMap();
				errors.add(rowError);
				Map errorObj = new HashMap();
				rowError.put("errors", errorObj);
				rowError.put("rowNum", new Integer(rowNum));
				for (Iterator j = fieldNames.iterator(); j.hasNext(); ) {
					String fieldName = (String)j.next();
					List error = er.getErrors(fieldName);
					if ((error != null) && (error.size() > 0)) {
						List errorStrings = new ArrayList();
						for (Iterator k = error.iterator(); k.hasNext(); ) {
							Map m = (Map)k.next();
							errorStrings.add(m.get("errorMessage"));
						}
						errorObj.put(fieldName, errorStrings);
					}
				}
			}

			++rowNum;
		}
		return errors;
	}
}
